package events.containers2;

import java.util.AbstractMap;
import java.util.EventListener;
import java.util.EventObject;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import zerdlib.events.DefaultListenable;
import zerdlib.events.GenericListenable;
import zerdlib.events.GenericListener;
import zerdlib.events.WeakGenericListener;
import zerdlib.events.containers.ListenableMap;
import zerdlib.events.containers.MapChangeEvent;

public class ListenableTreeMap<K, V> extends AbstractMap<K, V> implements ListenableMap<K, V> {

	protected DefaultListenable listenableManager = new DefaultListenable();
	@Override
	public void addListener(GenericListener toAddListener) {
		listenableManager.addListener(toAddListener);
	}

	@Override
	public void removeListener(EventListener toRemoveListener) {
		listenableManager.removeListener(toRemoveListener);
	}

	@Override
	public void suspendEvents() {
		listenableManager.suspendEvents();
	}

	@Override
	public void resumeEvents() {
		listenableManager.resumeEvents();
	}

	public void fireEvent(EventObject ev) {
		listenableManager.fireEvent(ev);
	}
	
	
	
	
	
	Map<K, V> map;
	private GenericListener valueChangeListener = new GenericListener() {
		@Override
		public void onEvent(EventObject ev) {
			Iterator<Entry<K, V>> it = map.entrySet().iterator();
			while(it.hasNext()) {
				Entry<K, V> e = it.next();
				if(e.getValue() == ev.getSource()) {
					fireEvent(new MapChangeEvent(ListenableTreeMap.this, MapChangeEvent.ELEMENT_CHANGED, e.getKey(), e.getValue()));
				}
			}
		}
	};
	
	private boolean containsReference(V x) {
		for(V v : map.values()) {
			if(v == x) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	public V put(K key, V value) {
		V oldValue = null;
		
		if(value instanceof GenericListenable && !containsReference(value)) {
			oldValue = map.put(key, value);
			WeakGenericListener.addWeakListener((GenericListenable)value, valueChangeListener);
		} else {
			oldValue = map.put(key, value);
		}

		fireEvent(new MapChangeEvent(this, MapChangeEvent.ELEMENT_ADDED, key, value));
		
		return oldValue;
	}
	
	@Override
	public Set<java.util.Map.Entry<K, V>> entrySet() {
		
		
		
		// TODO Auto-generated method stub
		return null;
	}
	
	
}
